package org.alex.samples.util;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAspect {

	@Pointcut("execution(* org.alex.samples.web.*.edit*(..)) || execution(* org.alex.samples.web.*.add*(..)) "  )
	public void allMethod() {};
	
	@After("allMethod()")
	public void afterLog(JoinPoint point){
		System.out.println("afterLog ---------- 最终通知");
		System.out.println("afterLog ---------- 目标方法为：" + point.getSignature().getDeclaringTypeName() + "."
				+ point.getSignature().getName());
		System.out.println("afterLog ---------- 参数为："+Arrays.toString(point.getArgs()));
		System.out.println("afterLog ---------- 被织入的目标对象为："+point.getTarget());
	}

	@AfterReturning(value="allMethod()",returning="returnValue")
	public void afterReturningLog(JoinPoint point, Object returnValue) {
		System.out.println("afterReturningLog ---------- 返回值后通知");
		System.out.println("afterReturningLog ---------- 目标方法为：" + point.getSignature().getDeclaringTypeName() + "."
				+ point.getSignature().getName());
		System.out.println("afterReturningLog ---------- 参数为："+Arrays.toString(point.getArgs()));
		System.out.println("afterReturningLog ---------- 返回值："+returnValue);
	}
	
	@AfterThrowing(throwing="ex",value="allMethod()")
	public void afterThrowingLog(Throwable ex) {
		System.out.println("afterThrowingLog ---------- 进入异常通知");
		System.out.println("afterThrowingLog ---------- 异常信息："+ex.getMessage() );
	}

	@Around("allMethod()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("AROUND ------- 进入环绕通知");
		Object obj=pjp.proceed();
		System.out.println("AROUND ------- 结束方法调用");
		return obj;
	}
}
